<?php

namespace app\common\service;

use app\common\model\File as FileMdl;

use think\facade\Db;

class Uploader
{

    /**
     * 文件上传
     */
    public static function upload($request)
    {
        $params = $request->all();
        if (!empty($params['total_count']) && !empty($params['total_count'])) {
            if (!empty($params['multi']) && $params['multi'] == 'true') {
                if ($params['total_count'] - $params['count'] <= 0) {
                    return json(['code' => 0, 'msg' => '最多上传' . $params['total_count'] . '张']);
                }
            }
        }

        $folder = request()->param('folder');
        !$folder && $folder = 'default';
        $field = request()->param('field');
        !$field && $field = 'file';

        $storage = $params['place'] ?? 'local';
        if ($storage == 'local') {
            // 上传到本地
            // 获取表单上传文件
            //$file = request()->file('file');
            $file = request()->file($field);
            $disk = request()->param('disk');
            if ($disk && $disk == 'public') {
                $disk = 'public';
            } else {
                $disk = 'uploads';
            }
            // 移动到框架应用根目录/public/uploads/ 目录下
            if ($file) {
                try {
                    //validate(['image' => 'fileSize:512000|fileExt:jpg,jpeg,png,gif'])->check(['image' => $file]);
//                validate([
//                    'file' => [
//                        'fileSize' => 1024,
//                        'fileExt' => 'jpg,jpeg,png,gif'
//                    ]
//                ])->check(['file' => $file]);
                    //$folderName = 'file/' . date('Y-m') . '/' . date('d');
                    $folderName = $folder . '/' . date('Y-m') . '/' . date('d');
                    $rename = request()->param('rename');
                    //$pathInfo = pathinfo($file);
                    if ($rename == 'false') {
                        //$saveName = \think\facade\Filesystem::disk($disk)->putFileAs($folderName, $file, date('His') . '_' . $file->getOriginalName());
                        $saveName = date('His') . '_' . $file->getOriginalName();
                    } else {
                        //$saveName = \think\facade\Filesystem::disk($disk)->putFile($folderName, $file, 'uniqid');  // file/2019-08/30/5d687a3d8c6d5.jpg
                        //$saveName = $file->md5() . '.' . $file->getOriginalExtension();
                        $saveName = uniqid() . '.' . $file->getOriginalExtension();
                    }
                    $info = $file->move($disk . '/' . $folderName, $saveName);
                    if ($info) {
                        //$file_ext  = $file->extension();
                        $file_ext  = $file->getOriginalExtension();
                        $file_type = FileService::typeJudge($file_ext);
                        $file_size = $info->getSize();
                        // 插入uploads表记录
                        $fileData = [
                            //'id' => get_UUID(),
                            'created_at' => time(),
                            'file_url' => $saveName,
                            'file_type' => $file_type,
                            'file_size' => $file_size,
                            'file_ext' => $file_ext,
                            'folder' => $folder,
                            'storage' => $storage,
                            'status' => 0
                        ];
                        FileMdl::insert($fileData);
                        return json([
                            'code' => 1,
                            'msg' => '上传成功',
                            'filename' => $_FILES[$field]['name'],
                            'filesize' => $_FILES[$field]['size'],
                            'filepath' => $saveName,
                            'full_filepath' => asset(config('path.upload_path') . $saveName),
                            'result' => []
                        ]);
                    } else {
                        // 上传失败获取错误信息
                        return json(['code' => 0, 'msg' => 'error']);
                    }
                } catch (\think\exception\ValidateException $validateEx) {
                    return json(['code' => 0, 'msg' => $validateEx->getMessage() . ', 仅支持jpg,jpeg,png,gif类型，且最大500KB']);
                } catch (\Exception $e) {
                    return json(['code' => 0, 'msg' => $e->getMessage()]);
                }
            } else {
                return json(['code' => 0, 'msg' => '上传失败']);
            }
        } elseif ($storage == 'qiniu') {
            // 上传到七牛
            $qiniu = new Qiniu();
            $result = $qiniu->uploadFile($_FILES[$field]);
            if ($result['code'] == 1) {
                $filepath = config('filesystem.disks.qiniu.url') . $result['key'];
                // 插入files表记录
                $fileData = [
                    //'id' => get_UUID(),
                    'created_at' => time(),
                    'file_url' => $filepath,
                    'storage' => $storage,
                    'status' => 0
                ];
                FileMdl::insert($fileData);

                return json([
                    'code' => 1,
                    'msg' => '上传成功',
                    'filename' => $_FILES[$field]['name'],
                    'filesize' => $_FILES[$field]['size'],
                    'filepath' => $filepath,
                    'full_filepath' => $filepath,
                    'result' => $result
                ]);
            } else {
                return json(['code' => 0, 'msg' => $result['msg']]);
            }
        }
    }

    /**
     * 分片上传
     */
    public static function sliceUpload($request)
    {
        $params = $request->all();
        $folder = $params['folder'];
        !$folder && $folder = 'slice';
        $field = $params['field'];
        !$field && $field = 'file';

        $storage = $params['place'] ?? 'local';
        if ($storage == 'local') {
            $file = request()->file($field);
            $page = $request->param('page');
            $totalPage = $request->param('total_page');
            $originalName = $request->param('file_name');

            if ($file) {
                $ext = pathinfo($originalName, PATHINFO_EXTENSION);; // 扩展名
                //$realPath = $file->getRealPath(); // 临时文件的绝对路径

                $folderName = $folder . '/' . date('Y-m') . '/' . date('d');
                $filename = $folderName . '/' . $originalName;
                $saveFilename = $folderName . '/' . uniqid() . '.' . $ext;

                $saveName = \think\facade\Filesystem::disk('uploads')->putFileAs($folderName, $file, $originalName. '_' . $page);
                // 判断是否是最后一块，如果是则进行文件合成并且删除文件块
                if ($page == $totalPage) {
                    for ($i = 1; $i <= $totalPage; $i++) {
                        $blob = \think\facade\Filesystem::disk('uploads')->path($filename . '_' . $i);
                        $blob = file_get_contents('compress.zlib://'. $blob); // 没有这一步文件就打不开
                        file_put_contents(public_path('uploads') . $saveFilename, $blob, FILE_APPEND);
                    }
                    // 合并完删除文件块
                    for ($i = 1; $i <= $totalPage; $i++) {
                        \think\facade\Filesystem::disk('uploads')->delete($filename . '_' . $i);
                    }
                }

                if ($saveName) {
                    $code = 2;
                    $msg = '分片上传中';
                    if ($page == $totalPage) {
                        $code = 1;
                        $msg = '上传成功';
                    }
                    return json([
                        'code' => $code,
                        'msg' => $msg,
                        'filepath' => $saveFilename,
                        'full_filepath' => asset(config('path.upload_path') . $saveFilename),
                    ]);
                } else {
                    return json([
                        'code' => 0,
                        'msg' => '上传失败'
                    ]);
                }
            }
        }
    }
}
